from flask import Blueprint, request, jsonify, current_app
from flask_jwt_extended import jwt_required, get_jwt_identity
from models import User, Message, db
from models.audit import AuditLog
from utils.auth import require_authentication, require_role, get_current_user, ROLE_ADMIN, ROLE_USER
from utils.encryption import EncryptionUtils
from flask import current_app
from utils.validation import validate_user_update_data
from sqlalchemy import func, or_
import uuid
import datetime
from typing import List, Dict, Any
from utils.audit import log_audit_event

users_bp = Blueprint('users', __name__, url_prefix='/api/users')

def get_user_with_relations(user_id: str) -> User:
    """获取包含关联数据的用户对象（优化查询）"""
    return User.query.get(uuid.UUID(user_id))

@users_bp.route('/', methods=['GET'])
@jwt_required()
@require_authentication
@require_role(ROLE_ADMIN)
def get_all_users(current_user):
    """获取所有用户（带分页和过滤）"""
    try:
        logger = current_app.logger
        redis_client = current_app.redis_client
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 20, type=int)
        role = request.args.get('role')
        active = request.args.get('active', type=bool)
        
        query = User.query
        
        if role:
            query = query.filter_by(role=role)
        if active is not None:
            query = query.filter_by(is_active=active)
        
        users = query.order_by(User.created_at.desc()).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        user_list = []
        for user in users.items:
            user_data = {
                'id': str(user.id),
                'username': user.username,
                'role': user.user_role,
                'online': user.online,
                'active': user.is_active,
                'created_at': user.created_at.isoformat(),
                'updated_at': user.updated_at.isoformat(),
                'last_login': user.last_login.isoformat() if user.last_login else None
            }
            user_list.append(user_data)
        
        return jsonify({
            'status': 'success',
            'total': users.total,
            'pages': users.pages,
            'current_page': users.page,
            'users': user_list
        }), 200
        
    except Exception as e:
        logger.error(f"Get all users error: {str(e)}", exc_info=True)
        return jsonify({
            'status': 'error',
            'message': 'Failed to get users'
        }), 500

@users_bp.route('/<string:user_id>', methods=['GET'])
@jwt_required()
@require_authentication
def get_user(current_user, user_id):
    """获取单个用户信息（增强版）"""
    try:
        logger = current_app.logger
        redis_client = current_app.redis_client
        user_uuid = uuid.UUID(user_id)
        
        # 权限检查：管理员可查看所有用户，普通用户只能查看自己
        if current_user.user_role != ROLE_ADMIN and current_user.id != user_uuid:
            return jsonify({
                'status': 'error',
                'code': 403,
                'message': 'Permission denied'
            }), 403
        
        user = get_user_with_relations(user_id)
        if not user:
            return jsonify({
                'status': 'error',
                'code': 404,
                'message': 'User not found'
            }), 404
        
        user_data = {
            'id': str(user.id),
            'username': user.username,
            'role': user.user_role,
            'online': user.online,
            'active': user.is_active,
            'created_at': user.created_at.isoformat(),
            'updated_at': user.updated_at.isoformat(),
            'last_login': user.last_login.isoformat() if user.last_login else None,
            'login_attempts': user.failed_login_attempts,
            'locked_until': user.login_locked_until.isoformat() if user.login_locked_until else None
        }
        
        # 管理员可查看额外信息
        if current_user.user_role == ROLE_ADMIN:
            user_data['auth_logs'] = [
                {
                    'event_type': log.event_type,
                    'timestamp': log.timestamp.isoformat(),
                    'ip_address': log.ip_address
                }
                for log in user.auth_logs
            ]
        
        return jsonify({
            'status': 'success',
            'user': user_data
        }), 200
        
    except ValueError:
        return jsonify({
            'status': 'error',
            'code': 400,
            'message': 'Invalid user ID format'
        }), 400
    except Exception as e:
        logger.error(f"Get user error: {str(e)}", exc_info=True)
        return jsonify({
            'status': 'error',
            'message': 'Failed to get user'
        }), 500

@users_bp.route('/<string:user_id>', methods=['PUT'])
@jwt_required()
@require_authentication
def update_user(current_user, user_id):
    """更新用户信息（增强版）"""
    try:
        logger = current_app.logger
        redis_client = current_app.redis_client
        user_uuid = uuid.UUID(user_id)
        
        # 权限检查
        if current_user.user_role != ROLE_ADMIN and current_user.id != user_uuid:
            return jsonify({
                'status': 'error',
                'code': 403,
                'message': 'Permission denied'
            }), 403
        
        user = User.query.get(user_uuid)
        if not user:
            return jsonify({
                'status': 'error',
                'code': 404,
                'message': 'User not found'
            }), 404
        
        data = request.get_json()
        if not data:
            return jsonify({
                'status': 'error',
                'code': 400,
                'message': 'No update data provided'
            }), 400
        
        # 输入验证
        validation = validate_user_update_data(data)
        if validation.get('status') == 'error':
            return jsonify(validation), 400
        
        # 记录原始数据用于审计
        old_data = {
            'username': user.username,
            'role': user.user_role,
            'active': user.is_active
        }
        
        # 更新用户名
        if 'username' in data:
            new_username = data['username']
            if new_username != user.username:
                if User.query.filter_by(username=new_username).first():
                    return jsonify({
                        'status': 'error',
                        'code': 400,
                        'message': 'Username already exists'
                    }), 400
                user.username = new_username
        
        # 更新角色
        if 'role' in data and current_user.user_role == ROLE_ADMIN:
            user.user_role = data['role']
        
        # 更新激活状态
        if 'active' in data and current_user.user_role == ROLE_ADMIN:
            user.is_active = data['active']
        
        # 密码更新（需要原密码验证）
        if 'password' in data and 'current_password' in data:
            if not user.check_password(data['current_password']):
                return jsonify({
                    'status': 'error',
                    'code': 401,
                    'message': 'Current password is incorrect'
                }), 401
            
            user.set_password(data['password'])
        
        db.session.commit()
        
        # 记录审计日志
        log_audit_event(
            user_id=str(current_user.id),
            event_type='USER_UPDATED',
            object_id=str(user.id),
            old_data=old_data,
            new_data=data
        )
        
        return jsonify({
            'status': 'success',
            'message': 'User updated successfully'
        }), 200
        
    except ValueError:
        return jsonify({
            'status': 'error',
            'code': 400,
            'message': 'Invalid user ID format'
        }), 400
    except Exception as e:
        db.session.rollback()
        logger.error(f"Update user error: {str(e)}", exc_info=True)
        return jsonify({
            'status': 'error',
            'message': 'Failed to update user'
        }), 500

@users_bp.route('/<string:user_id>', methods=['DELETE'])
@jwt_required()
@require_authentication
@require_role(ROLE_ADMIN)
def delete_user(current_user, user_id):
    """删除用户（增强版，硬删除前的安全处理）"""
    try:
        logger = current_app.logger
        redis_client = current_app.redis_client
        user_uuid = uuid.UUID(user_id)
        user = User.query.get(user_uuid)
        
        if not user:
            return jsonify({
                'status': 'error',
                'code': 404,
                'message': 'User not found'
            }), 404
        
        # 不能删除自己
        if current_user.id == user_uuid:
            return jsonify({
                'status': 'error',
                'code': 400,
                'message': 'Cannot delete yourself'
            }), 400
        
        # 软删除处理（保留消息但标记为已删除）
        user.is_active = False
        user.username = f"deleted_{user.username}_{uuid.uuid4()}"
        
        # 加密用户敏感数据
        from utils.encryption import EncryptionUtils
        user.encrypted_master_key = EncryptionUtils.binary_to_hex(
            EncryptionUtils.aes_encrypt(
                EncryptionUtils.generate_symmetric_key(),
                EncryptionUtils.hex_to_binary(user.encrypted_master_key)
            )[0]
        )
        user.kek_salt = EncryptionUtils.binary_to_hex(os.urandom(16))
        
        db.session.commit()
        
        # 记录审计日志
        log_audit_event(
            user_id=str(current_user.id),
            event_type='USER_DELETED',
            object_id=str(user.id),
            data={'username': user.username}
        )
        
        return jsonify({
            'status': 'success',
            'message': 'User deleted successfully'
        }), 200
        
    except ValueError:
        return jsonify({
            'status': 'error',
            'code': 400,
            'message': 'Invalid user ID format'
        }), 400
    except Exception as e:
        db.session.rollback()
        logger.error(f"Delete user error: {str(e)}", exc_info=True)
        return jsonify({
            'status': 'error',
            'message': 'Failed to delete user'
        }), 500

@users_bp.route('/<string:user_id>/activity', methods=['GET'])
@jwt_required()
@require_authentication
def get_user_activity(current_user, user_id):
    """获取用户活动统计（增强版）"""
    try:
        user_uuid = uuid.UUID(user_id)
        
        # 权限检查
        if current_user.user_role != ROLE_ADMIN and current_user.id != user_uuid:
            return jsonify({
                'status': 'error',
                'code': 403,
                'message': 'Permission denied'
            }), 403
        
        user = User.query.get(user_uuid)
        if not user:
            return jsonify({
                'status': 'error',
                'code': 404,
                'message': 'User not found'
            }), 404
        
        # 消息统计（使用子查询优化）
        message_stats = db.session.query(
            func.count(Message.id).label('total_messages'),
            func.count(func.distinct(Message.sender_id)).label('unique_senders'),
            func.count(func.distinct(Message.receiver_id)).label('unique_receivers')
        ).filter(
            or_(
                Message.sender_id == user_uuid,
                Message.receiver_id == user_uuid
            )
        ).first()
        
        # 登录统计（近30天）
        login_stats = db.session.query(
            func.date_trunc('day', AuthLog.timestamp).label('date'),
            func.count().label('login_count')
        ).filter(
            AuthLog.user_id == user_uuid,
            AuthLog.event_type == 'LOGIN_SUCCESS',
            AuthLog.timestamp >= (datetime.datetime.now() - datetime.timedelta(days=30))
        ).group_by(
            func.date_trunc('day', AuthLog.timestamp)
        ).order_by(
            func.date_trunc('day', AuthLog.timestamp).desc()
        ).all()
        
        return jsonify({
            'status': 'success',
            'user': {
                'id': str(user.id),
                'username': user.username,
                'role': user.role,
                'active': user.active
            },
            'message_activity': {
                'total_messages': message_stats.total_messages,
                'unique_senders': message_stats.unique_senders,
                'unique_receivers': message_stats.unique_receivers
            },
            'login_activity': [
                {
                    'date': log.date.strftime('%Y-%m-%d'),
                    'login_count': log.login_count
                }
                for log in login_stats
            ]
        }), 200
        
    except ValueError:
        return jsonify({
            'status': 'error',
            'code': 400,
            'message': 'Invalid user ID format'
        }), 400
    except ValueError:
        return jsonify({"error": "Invalid user ID format"}), 400
    except Exception as e:
        logger.error(f"Get user activity error: {str(e)}", exc_info=True)
        return jsonify({
            'status': 'error',
            'message': 'Failed to get user activity'
        }), 500

@users_bp.route('/search', methods=['GET'])
@jwt_required()
@require_authentication
def search_users(current_user):
    """搜索用户（带索引和分页）"""
    try:
        query = request.args.get('query', '').strip()
        page = request.args.get('page', 1, type=int)
        per_page = request.args.get('per_page', 10, type=int)
        
        if not query:
            return jsonify({
                'status': 'success',
                'total': 0,
                'users': []
            }), 200
        
        # 使用ILIKE进行模糊查询（建议生产环境使用全文索引）
        users = User.query.filter(
            User.username.ilike(f'%{query}%'),
            User.is_active == True
        ).order_by(
            User.username
        ).paginate(
            page=page, per_page=per_page, error_out=False
        )
        
        user_list = []
        for user in users.items:
            user_list.append({
                'id': str(user.id),
                'username': user.username,
                'online': user.online,
                'role': user.role,
                'active': user.active
            })
        
        return jsonify({
            'status': 'success',
            'total': users.total,
            'current_page': users.page,
            'users': user_list
        }), 200
        
    except Exception as e:
        logger.error(f"Search users error: {str(e)}", exc_info=True)
        return jsonify({
            'status': 'error',
            'message': 'Failed to search users'
        }), 500

@users_bp.route('/me', methods=['GET'])
@jwt_required()
@require_authentication
def get_current_user(current_user):
    """获取当前用户信息（简化版）"""
    try:
        user = get_user_with_relations(str(current_user.id))
        
        if not user:
            return jsonify({
                'status': 'error',
                'code': 404,
                'message': 'User not found'
            }), 404
        
        user_data = {
            'id': str(user.id),
            'username': user.username,
            'role': user.user_role,
            'online': user.online,
            'active': user.is_active,
            'created_at': user.created_at.isoformat(),
            'last_login': user.last_login.isoformat() if user.last_login else None
        }
        
        return jsonify({
            'status': 'success',
            'user': user_data
        }), 200
        
    except Exception as e:
        current_app.logger.error(f"Get current user error: {str(e)}", exc_info=True)
        return jsonify({
            'status': 'error',
            'message': 'Failed to get current user'
        }), 500